{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [128,128,128] ; Dense Layers [128,128,128] \n",
    "### CNN regularized with dropout\n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[  2.23553\n",
      "X_train             -> array([[[ -1.49427662e-02,  -5.38582681e-03,   3.2\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([1, 4, 1, ..\n",
      "y_train             -> array([1, 5, 7, ..., 4, 3, 3])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.24609375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 1 training accuracy : 0.3486328125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 2 training accuracy : 0.4765625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 3 training accuracy : 0.546875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 4 training accuracy : 0.5380859375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 5 training accuracy : 0.548828125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 6 training accuracy : 0.5654296875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 7 training accuracy : 0.62890625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 8 training accuracy : 0.615234375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Epoch 9 training accuracy : 0.603515625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Training took 37.636944 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 128\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 128\n",
    "ksize_conv2 = ksize_conv1\n",
    "stride_conv2 = stride_conv1\n",
    "\n",
    "feature_map3 = 128\n",
    "ksize_conv3 = ksize_conv1\n",
    "stride_conv3 = stride_conv1\n",
    "\n",
    "pool_layer_maps = 128\n",
    "conv_drop_rate = 0.25\n",
    "\n",
    "n_fully_conn1 = 128\n",
    "n_fully_conn2 = 128\n",
    "n_fully_conn3 = 128\n",
    "dense_drop_rate = 0.5\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "training_ = tf.placeholder_with_default(False, shape=[])\n",
    "\n",
    "xavier_init = tf.contrib.layers.xavier_initializer()\n",
    "relu_act = tf.nn.relu\n",
    "\n",
    "# ------------------ Convolutional and pooling layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = relu_act)\n",
    "    return convolutional_layer\n",
    "\n",
    "def pool_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, xavier_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, xavier_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "conv_layer3 = convolutional_layer(conv_layer2, feature_map3, ksize_conv3, xavier_init, stride_conv3, padding = \"SAME\")\n",
    "\n",
    "pool_layer_flat = pool_layer(conv_layer3, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps)\n",
    "\n",
    "pool_layer_drop = tf.layers.dropout(pool_layer_flat, conv_drop_rate, training = training_)\n",
    "\n",
    "# ----------------- Fully connected layers -------------------\n",
    "\n",
    "def dense_layer(input_layer, n_neurons, kernel_init, activation):\n",
    "    fully_conn = tf.layers.dense(inputs = input_layer, units = n_neurons, activation = activation,\n",
    "                                kernel_initializer = kernel_init)\n",
    "    return fully_conn\n",
    "        \n",
    "dense_layer1 = dense_layer(pool_layer_drop, n_fully_conn1, xavier_init, relu_act)\n",
    "\n",
    "dense_layer2 = dense_layer(dense_layer1, n_fully_conn2, xavier_init, relu_act)\n",
    "\n",
    "dense_layer3 = dense_layer(dense_layer2, n_fully_conn3, xavier_init, relu_act)\n",
    "\n",
    "dense_layer_drop = tf.layers.dropout(dense_layer3, dense_drop_rate, training = training_)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer_drop, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_regtech1\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch, training_: True})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.12174999713897705\n",
      "CNN's test accuracy on -18dB SNR samples = 0.11949999630451202\n",
      "CNN's test accuracy on -16dB SNR samples = 0.13650000095367432\n",
      "CNN's test accuracy on -14dB SNR samples = 0.15649999678134918\n",
      "CNN's test accuracy on -12dB SNR samples = 0.1889999955892563\n",
      "CNN's test accuracy on -10dB SNR samples = 0.22624999284744263\n",
      "CNN's test accuracy on -8dB SNR samples = 0.31025001406669617\n",
      "CNN's test accuracy on -6dB SNR samples = 0.4097500145435333\n",
      "CNN's test accuracy on -4dB SNR samples = 0.5007500052452087\n",
      "CNN's test accuracy on -2dB SNR samples = 0.6172500252723694\n",
      "CNN's test accuracy on 0dB SNR samples = 0.715499997138977\n",
      "CNN's test accuracy on 2dB SNR samples = 0.7570000290870667\n",
      "CNN's test accuracy on 4dB SNR samples = 0.7914999723434448\n",
      "CNN's test accuracy on 6dB SNR samples = 0.7942500114440918\n",
      "CNN's test accuracy on 8dB SNR samples = 0.7990000247955322\n",
      "CNN's test accuracy on 10dB SNR samples = 0.8132500052452087\n",
      "CNN's test accuracy on 12dB SNR samples = 0.8037499785423279\n",
      "CNN's test accuracy on 14dB SNR samples = 0.8022500276565552\n",
      "CNN's test accuracy on 16dB SNR samples = 0.7979999780654907\n",
      "CNN's test accuracy on 18dB SNR samples = 0.8115000128746033\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmMAAAGPCAYAAAAQptcZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XmclXX5//HXNWfODAwgI5tsyowaaLmQll/NMkrLrTLN\nTJKUXDDTsAXFSFPUH25oatoiUGmUpqa5ZKYp2IZFKS65IDqDrCLLsA3DnJm5fn/cZ+Awc+ZwgLPe\n5/18PObh3Pe5535/7sNDuOb+XOdzm7sjIiIiIvlRlu8BiIiIiJQyFWMiIiIieaRiTERERCSPVIyJ\niIiI5JGKMREREZE8UjEmIiIikkcqxkRKiJkdZGb3m9nbZtZkZivN7LX4vpM6HNuW8HV/h9fOT3jt\nhwn7r+zwc23xnDozm25mQ3N1rTuiw/W0mdl1+R6TiJQOFWMiJcLMPg7MBU4FaoAosDswAvgScGKS\nH2tfiPAUMzswxevJ9rd/RYG9gLOBv5tZ1U5eQjadwbZjPiO/wxGRUqJiTKR0TCQojFqBk4AeQB/g\n/4CrgXdS/KwBk3cwb7K7R4APAu/G9+0Zzy4YZjYMODJxFzDEzEblZ0TpM7PKfI9BRHadijGR0vGB\n+H/XA0+7e5O7r3X3/7j7ZHe/voufayEoUE4ys5E7GurubwIPJezaK9XxZvZwfKqwxcwGJuw3M1sa\nf+2d+L5uZnadmb1hZuvNbEN8CvZBMzsszSF+jeD6AH6RsH9MF+M7xcyeik/xbjazxWb2ezPrnXDM\nHmb2IzN708w2mdlaM/uvmX0t4Zj2KdFnO5y/0/4O079fNLMZZrYS2BR//dNm9nh8Onh9fFzvmtmv\nzWyfJNfwKTP7g5ktjx+73MyeMLNaMzs4IevODj/3rYTXvpLm+ysi26FiTKR0LIr/txp4y8x+amZn\nmlnNdn6uAfgjO3d3rJ0lfL9iO8e2F0QGJP6DPwoYSDCN+Mv4vpsJ7vh9AKgCuhNMwZ4MfCTNsX01\n/t+W+LmWxbO/1PHOk5lNBR4EjiGY4i0HBgFfBHrHj9kHeAm4GNgXqAB6AiOBT3XITjXN29X+acDY\neH5bfP9HgeMJCt2q+LiGEEy3/sPM+iRcw7eAvwBfAPrHj+0PHAvs6e4vAc/FDz+jw7Ry+5/HKrYt\nsEVkF6gYEykdtxL84+3AUOB84FfAO2b2DzM7OMXPtjfpf87MDt2RUDPbj6A4AtgAPLadH3kCWB7/\n/qsJ+9u/d4JxA3wivv08QUHRA9gP+CbwehpjOzR+vAPPuvtq4OH4y7sRFCztx34U+G782LUEvXe7\nERRA3wEa44f+GBgQP+4hgoKsF3AUsM1dsF1wLEHR1f5n9lT8/HsQTEX3BabEX+tP/C6fmQ0Bborv\njwHjCIq6QQQ9fe/HX7s1/t9exPvn4h++OCJ+Xfe4eyxD1yJS8lSMiZQId/8jcDQwi+AuUGLD+hHA\nY0ma6y3+sy+ytYhK9+7YVWbWBrwGDAMWACe6+8rtjLMV+HU8+yNmtreZRYFT2Fo0td/lq4sf90GC\ngnEMQSHyC3eflcYYz0z4/vcd/gvbTlV+IeH7m939YXff6O5L3P12d19pZt0I7ppBUHie6e517t7o\n7v9w95lpjGl7prr7X9x9s7v/L75vKUHRNAfYCKwGfpDwMyPi/z2O4E4dwEx3n+Hu69x9hbvf7e7t\nBeyjwNsE7+034vtGs/UO54wMXIeIxKkYEykh7v6cux8D9CP49OTPCO6QQDCtdUTHH0n4/sr4f48H\nDk8nLuELginEiq4P30Zi79ZX45m7x7enJ7z2HeDfBHeovgXcBfwTWGJmx5CCmZUBpyXsWmBmHyKY\ngttIUHgclzDFt0fCsV3ddetDMO3nwLvuvinVGJKMKZLGYfM6/IwR3HH7BrA3wXuc+L5D8N7Dttfw\nWlcB7u4Ed/gARsb779qnKP/l7l3+rIjsOBVjIiXCzHq1fx+/G/Kku18I3J1wWJ/OP7nlZ+YBfyAo\nUpI2t3cwGagkuGPTSlDsPZzOWmPxpv/n45uj418Q9K/9IeG4d9z9cGAw8BmCPq1lBHfHfkxqnyUo\nTjx+Tc8CrxAUOz3ix5QDp8e/fy/hZ/fv4pyr2fqBh73id8q60hz/b+Ixe29nzBBv2k9wUHw8DvwP\nGBb/FGuyT62mcw3tfgGsi39/A3BIPOOuNMYoIjtAxZhI6fhD/NN1J5pZPzMrN7MDCHqN2m2vz+oq\ngn+Q0/q7w91b3P0+oP1TeT2Brj612dEvCIqa/QjWQXPgN+7eXsRgZhPM7DSCOz9/B+4nmLIztvOp\nTYJPUW4ZahdfsLXwfLQ9FviumZ1sZj3MbLCZXWRm/dy9CXg64VrviX9CscrM/i/x05TAwvi5DjSz\nPeNTsdem8b501JLw/WagMb5cx6Qkxz5JUAQa8DUzO9vMeptZfzP7mpltKdDcfQNb/ww+Gd+9geA9\nFpEMUjEmUjoqCO5SPUbwicZm4GWCfiIH/uDur3b4mcRPQeLurxD0VBk75hqCuywGnG5mB6XxM/cR\nNMUbwR0q2PopynbHxo97B2giuCt2KMH1PNnVic2sB1vvHG0Gqt09kvgFLIln/5+Z7ePucwk+vekE\nn5z8PcEyIYuB2wga6gHGs/UDCKcS9F5tIOjnSvw05W/i/+0RP6YBOKF9iF2+K529wdYi+lBgJUEv\nXftdzi3ncvclwCUEH+QoJ5jyXUNwx+xXBM3+iW5n64c+HLjX3RsRkYxSMSZSOi4n+JTcXIK7R80E\nvVEvAt9n63Rcu453iNpdRTDtmPayDO6+CpjK1inB7T5uKH5n5sGEMbwU/yBBol8RLLuxiGD6rhl4\ni6BoOpOunUJwN82BR9x9fZJjZtLh7pi7X0Jwl+4vBFOSzQRF28MEn7DE3d8mWMbiNmA+QZG4HniB\n4MMT7a4Hbon//GaC5SSOpOv3Pdm+9g88fB74E0HB+z7Bn/P4ZOdy9x8TfJCjvSiPERRjT7J1+ZP2\nY+uBR9ha0CX264lIhljQpykiIrKt+AcKZgEfB/7r7h/N85BEQql8+4eIiEipMbM3CD4I0ZfgztpV\neR2QSIjpzpiIiHRiZq0E/WLvAte7+7Q8D0kktFSMiYiIiOSRGvhFRERE8qhoe8bMTLf0REREpGi4\ne9Jla4r6zpi75+zryiuvVJ7yCi5LecpTXunkhfnaSiEvlaIuxnKpvr5eecoruCzlKU95pZMX5msr\nhbxUVIyJiIiI5FHkqquuyvcYdsrkyZOvyuXYq6urqampUZ7yCipLecpTXunkhfnaSiFv8uTJXHXV\nVZOTvVa0S1uYmRfr2EVERKS0mBkexgb+XJo9e7bylFdwWcpTnvJKJy/M11YKeamoGBMRERHJI01T\nioiIiGSZpilFRERECpSKsTSFfS5becWZpTzlKa908sJ8baWQl4qKMREREZE8Us+YiIiISJapZ0xE\nRESkQKkYS1PY57KVV5xZylOe8konL8zXVgp5qagYExEREckj9YyJiIiIZJl6xkREREQKlIqxNIV9\nLlt5xZmlPOUpr3TywnxtpZCXiooxERERkTxSz5iIiIhIlqlnTERERKRAqRhLU9jnspVXnFnKU57y\nSicvzNdWCnmpqBgTERERySP1jImIiIhkmXrGRERERAqUirE0hX0uW3nFmaU85SmvdPLCfG2lkJeK\nijERERGRPFLPmIiIiEiWFVTPmJkdZ2ZvmNl8M5uY5PW9zOwvZvaSmT1rZoNzPUYRERGRXMlpMWZm\nZcAdwLHAh4DRZrZfh8OmAr9y94OBq4HrcznGroR9Llt5xZmlPOUpr3TywnxtpZCXSq7vjB0GvOXu\nC909BtwHnNThmA8CzwK4++wkr4uIiIiERk57xszsS8Cx7j4uvj0GOMzdxyccMxP4l7v/2MxOAR4A\n+rn7mg7nUs+YiIiIFIVUPWPluR5Lkn0dK6pLgDvMbCzwV2AJ0JLsZGPHjqWmpgaA6upqRo4cyahR\no4Cttx+1rW1ta1vb2ta2tnO93f59fX092+XuOfsCDgeeTNi+DJiY4vgewLtdvOa5NGvWLOUpr+Cy\nlKc85ZVOXpivrRTy4nVL0nqnbPvlWkbNBfY1s2FmVgGcDjyaeICZ9TWz9jto3wd+keMxioiIiORM\nztcZM7PjgNsIPjwww92vN7PJwFx3fzzeV3Yd0EYwTXmhB83+Hc/juR67iIiIyM5I1TOmRV9FRERE\nsqygFn0tVokNecpTXqFkKU95yiudvDBfWynkpaJiTERERCSPNE0pIiIikmWaphQREREpUCrG0hT2\nuWzlFWeW8pSnvNLJC/O1lUJeKirGRERERPJIPWMiIiIiWaaeMREREZECpWIsTWGfy1ZecWYpT3nK\nK528MF9bKeSlomJMREREJI/UMyYiIiKSZeoZExERESlQKsbSFPa5bOUVZ5bylKe80skL87WVQl4q\nKsZERERE8kg9YyIiIiJZpp4xERERkQKlYixNYZ/LVl5xZilPecornbwwX1sp5KWiYkxEREQkj9Qz\nJiIiIpJl6hkTERERKVAqxtIU9rls5RVnlvKUp7zSyQvztZVCXioqxkRERETySD1jIiIiO6iurp4p\nU6ezsiFGv+ookyacS21tTZ5HJenI159dqp4xFWMiIiJpamtz/vXCAi747i30HnExkWgVrbFGNr59\nG7+bdin77FOb7yFKCnV19YwedyOVNeO3/Nltrr+de++6NOsFWUE18JvZcWb2hpnNN7OJSV7f08ye\nNbMXzGyemR2f6zEmE/a5bOUVZ5bylKe87OR19cv+ps3OVy/46ZZCbM2SOUSiVfTY52KmTJ2R9Gee\n/c9GXl7QxPJVLbS07vxNhGJ9L/Od19rqLHovxt/nNTLuuz/dUoi1/9lV1oxnytTpWclOV3kuw8ys\nDLgDOBpYCsw1s0fc/Y2Ewy4HfufuPzez/YEnAP2qISIiWbFmfSt1S2PUL41RvyxG3dJmFi6L8bsp\nQ+heue09ix7dy6iqdCLRqm32R6JVrF4b63TuDZvauPYXq7Zsm0Gf3SIM7l/Ord8ZgNm2N0rcHXco\nK9u6v31a7fU332b/B/6S9Wm1XOdl04xHG7j/L+uItQTbdYs2Uzuo85/dyobOf3a5lNNpSjM7HLjS\n3Y+Pb18GuLvfkHDMT4F33P0mMzsCuMndP57kXJqmFBERYNf6gE7/wRJWrGnttP+nE/dgxLDKTvvP\nu/By5jeP2aYga401MrxiJtPuvHabY1eva+XH96/h/TUtrFjTyuq1rbQ5DOob4TfXDOl07lVrWxl9\n+RL6VUfov3s50ZYlPPHwXfQ/4NtJp9U2N7fx7nstlEcgEjEiZVAeMSqjRnWvSFrXnyif03jp2tTU\nxrvvxVi4LMbC5S0sXB7jiAO7c+KRPTsde9/T67jr4QYG9IkwbGCU55+cCoPOTuvPLtMKpmfMzL4E\nHOvu4+LbY4DD3H18wjEDgaeA3YEq4Bh3fzHJuVSMiYhI0gJiw1u38a3xF7HJB1O/LLjrdfX5/ZIW\nV9fMWMl7q1uoHRyldnAFNYOi1AyOsnuvsk53rrrKS7dgaWl1Vja0snFTG/sMrej0+vx3m/nG9cu3\nZs29lb1GjuuyeFiwqJlx1y3vdJ69h0SZ/oNBnfa/vbiZC25YTnnEiEQgUmaUR2DvIRXc+K0BXRaa\nzYtmcNpZ36eq0qjqVsYefSJ89vDOxU9Lq7NxUxvdK8uoiCatOzrZkUL6kb+u57b71nTa/9n/68Fl\nZ/XttH/jpjbKDLp3K9uSpZ4xSDaIjhXVaOCX7r4ncCIwM+ujSkNY5s6VF64s5SmvUPPq6uo578LL\n+fgxoznvwsupq6vf6XOtXtfKgkXNvPRWE/98uZGn/7WRR55bT/2yYGppytTpnfqAen7gYiZfN4MH\nnlnP3NeaeL8hmIpM5opz+nHHJQP53hl9OeVTvThkv2702S2StBADqK2t4d67LmV4xUya509keMXM\ntP8xL48YA/uWJy3EAIbvVcGfbh3KPVcNYurFA9hzj7IthdGaJXOAbafVysuNfYZGGTYoytAB5Qzq\nG6F/dYQ+uyW/K9baBi2t0NTsbNzkrNvYxup1bazdENwZXNkQS5q3fGWMx/62gd/9ZT2/fHwtv5+1\nPun531kS4+RLl3DcxYv47Lfe5YuXLOarVyzhqmnvJz3+xZff5vNjrmd+8xjqNxzC/OYxfOa065h8\nx7ykx++xeznRcth7cJRRh1Rx1om9+eE5fRlz/G5Jj+/RvWxLIQa79meXTTntGQMWA3slbA8l6B1L\ndA5wLIC7P29m3cysn7uv7HiysWPHUlNTA0B1dTUjR45k1KhRwNa/cDK1PW/evIyeT3nhztO2tgtt\ne9my5Tz791d5/c236X3rDMZ85URGjz4943mtbc7Mmfdy3a2/Y49Db2Bjj5f4d/1mTjz1Yv744G3U\n1tbw01/+mYXLYwzd90gam9r437y/0dTsXHzesXzsoKpO5//BDY/z/KtN7D7kCGBrkXD1hBOoGRTl\n9TffZmOPlzq9Xt0Tvv753jQsmcPAvuV85v+Ozuj1Trvz2i3fL1xYv+Uf9F09/5x//nXL9ohh3fh3\n/WzKyrfe0Vu1cDbdo8E/nTWDopzxsTeTng8GdDr/B/aM8v1T3qatzTny46NoaXWee252/E7JIPpV\nR3knSd7AXisY/5XdaWxq48W5f6NnpRHcL9n2/C2tzuZV/6KpuY3eg45g3cY2Fs6fQ9PKKHBKp+On\nTJ1BpPpjrFvxEhAUfj0GHMnd06/jyot+1+n4j3ywG5ee9DaRiG1zvQteg6ED0nt/Fy6s54wvHwMc\nw6hRo5g9ezYLF9Zn/P+/9u/r6+vZnlxPU0aANwka+JcB/wZGu/vrCcf8Ebjf3e+ON/A/7e5Dk5xL\n05QiImlINjWz9s3b+NmPvsfhh+7b6fg5r2xi3vwmmluc5manucXZ3Owce0QPjjyoqtPx0/7QwCN/\nXU9zzGlp3f7U2o/vX83Dszd0Os83T63m1E93vsMx809rmf3fRnp0L6NH92CarEf3Mj59aBUHD++2\nQz1cxSbX02qZynN3Yi3Q2NRG4+bg3+rB/Trf/znhy5fS1P+iTvu7r7yDP95/405eRWFKNU2Z0ztj\n7t5qZhcR9ISVATPc/XUzmwzMdffHgQnANDP7DtAGnJXLMYqIhM2EH/58yz+uENx96D3iYn74/6bx\n1EM3dDp+3vwmHnim8zTUB/fu3G8F0NrmNDYF/+CagdGW9NOG7VNrH/1gd3pVBQVVe2HVo5sxbGA0\n6fnHHN+bMcf37vL6Jk04N2kBMemuS7v8mWJRWxtMq23TU5XFabVM5ZkZFVGoiEao7tX1cUMGVDC/\nubFTIT24f/Jp3LDSoq9pmj179pZbkMpTXqFkKU956Tjy+AlU1gafk1qzZM6W6Txf/GNmPXpTp+Pn\nzW/izYXNVESNimjwybyKqLH3kChDB3QumDY1tdHqUFFuRMth3EVXbLlT1Z6X7TtV2yzHMGKfnC3H\noL9bdk3inbh1K15itwEH56yhPtfvZ8HcGRMRkdz7wJ6V1MU6330YvmfyO10jh3dj5PBuaZ8/sUEa\ntr1T1Z6V7TtVtbU1W3q4cvkPrOya2tqtd+Je3/g2wyteyeqdv0KlO2MiIkVuU1Mbz/ynkX++3Mg1\n3+hPpGzbX77z8XF+PbtRZFsFs85YJqkYE5FSt3BZjEf/tp6nnt/IxnjP1pQL+nP4gd07HaviSCS/\nCmmdsaKV+FFV5SmvULKUV7p5P75/NV+/ZhkPz97AxibngH0q+cHX+3LIfsmnF2trg2m8i887nml3\nXpuzQqxY3s9iyAvztZVCXirqGRMRKUIf2LOCbhXGMYf14KSjena5iKiIFD5NU4qIFCh3Z9mq1qTr\nMzXHgvW/enbXBIdIMVDPmIhIEdnQ2MZT/9rIo39dz5r1bdw/ZTCVFSq6RIqZesYyIOxz2corzizl\nFW9esmc3LljUzM2/WcVpk5ZwxwNrePe9FiqixuIVLRnLDev7WQp5Yb62UshLRT1jIiI5lrjUxMYe\nLzG/+WBGj7uRQ446mzeWBc8TPGREJV84qhcfO6g75ZHkD6wWkXDQNKWISI519SzFvk138+nPX8IX\njurFXl08GkhEipNW4BcRKRAN61t5e/FmIkM6P7vRG9u46LQ+eRqZiOSLesbSFPa5bOUVZ5byiiev\nYX0rdz28hq9esZSFy1ppjTUCwbMiIbgz1q86+3fDwvJ+lmJemK+tFPJS0Z0xEZEsWrO+lfufXscj\nf91AU3PQWvHZz32VubNvo8c+FwO5eXajiBQu9YyJiGTRDfes4s/PbwTg8AO6ceYJvdmvplKPJxIp\nMVpnTEQkT95dHuOuPzTwteN3Y8SwynwPR0TyROuMZUDY57KVV5xZyiucvMamtqT79xoY5dpv9O+y\nECuW61Ne/vPCfG2lkJeKijERkV2wem0rP3lwDad+fwkLl8XyPRwRKUKaphQR2Qmr1rZy39PreOxv\nG2iOBX8XXfClar589G55HpmIFCKtMyYikkF/n9fItb9ctaUI+/jB3TnzhN7su2dFnkcmIsVI05Rp\nCvtctvKKM0t5+cnbv7YSAz4xsjvTJg3k6vP773QhVojXp7zCzAvztZVCXiq6MyYisoP69o7wm2sG\n02e3SL6HIiIhoJ4xERHotO7X+eeN5R9v9uHoj/TggH20JIWI7BqtMyYikkJdXT2jx91IZc14ItEq\nWmON1M29haEHjuXIj+7LTeMH5HuIIlLktM5YBoR9Llt5xZmlvMyYMnX6lkJszZI5RKJV1H70u7St\neJhvnlqd1ewwvp/KK/4s5eWWijERKXkrG2JEolXb7ItEqxjUr4zawfqEpIhkV86nKc3sOOBWgkJw\nhrvf0OH1W4BPAQ70APq7e58k59E0pYhkxHkXXs785jHbFGStsUaGV8xk2p3X5nFkIhIWBdMzZmZl\nwHzgaGApMBc43d3f6OL4i4CR7n5uktdUjIlIRiTrGdtcfzv33nWpHt4tIhlRSD1jhwFvuftCd48B\n9wEnpTh+NHBvTka2HWGfy1ZecWYpLzNqa2u4965LGV4xk+b5ExleMTNnhVgY30/lFX+W8nIr1+uM\nDQEWJWwvJijQOjGzvYAa4NnsD0tESo27Y7b1l9Ta2hqm3Xkts2fPZtSoUfkaloiUoFxPU54KfNbd\nx8W3xwAfdfeLkxx7KTAk2Wvx1/2ss86ipqYGgOrqakaOHLnlL9H2ilfb2ta2tjtuP/PsLH79xFpO\nO/kYTjiyZ97Ho21tazt82+3f19fXA3D33XcXTM/Y4cBV7n5cfPsywDs28cdfewH4prs/38W51DMm\nIjvlZw+t4f6/rKdnd+PXkwfTu6dW0heR7CqknrG5wL5mNszMKoDTgUc7HmRmI4DqrgqxfEisdJWn\nvELJUt6O++M/NnD/X9YTKYOrxvXvVIgV+/UpL7x5Yb62UshLJafFmLu3AhcBTwH/A+5z99fNbLKZ\nfS7h0NMJmvtFRDLmhTebuPXe1QB8e3QfDhnRLc8jEhHR45BEpES0tDpnXbWUZata+coxvTj/lN3z\nPSQRKSEFs85YJqkYE5EdtXBZjEf/tp4LT92dsrKkfyeKiGRFIfWMFa2wz2UrrzizlLdjhg2K8q3T\n+qQsxIr5+pQX7rwwX1sp5KWiYkxEREQkjzRNKSIiIpJlmqYUkZIz+4VGHnx2HfqlTUQKnYqxNIV9\nLlt5xZmlvORer9vM9Xev4icPNvDfN5qynrcrlKe8QsxSXm6pGBORUFm+qoXLf/4+zTHnhCN7cOh+\nWktMRAqbesZEJDQ2bmrj4pvf452lMT48opIbLhpAeURLWIhI/qlnTERKwu2/W807S2PsuUc5V53X\nX4WYiBQFFWNpCvtctvKKM0t52xr7uWoO2reSKd/sT6+qnfvrrZCvT3mlnRfmayuFvFTK8z0AEZFM\nGdSvnB99ZwBmuiMmIsVDPWMiIiIiWaaeMREREZECpWIsTWGfy1ZecWaVct7qda38PguLuhbK9SlP\nefnMUl5updUzZmb7ufsb2R6MiEg6Nje38cOfv89rdc00bna+dnzvfA9JRGSnpdUzZmZtwBxgOnC/\nu2/M9sC2Rz1jIqXJ3bn2l6uY9Z9GBvSJ8JNLBtKndyTfwxIRSSkTPWMHAf8GbgCWmdl0MzsiUwMU\nEUnX3X9cy6z/NFLVzZhyQX8VYiJS9NIqxtz9VXf/DjAY+DowEPirmb1mZt8zswHZHGQhCPtctvKK\nM6vU8mb/dyP3PLGOMoMrzunH3kMqspqXC8pTXiFmKS+3dqiB391b3P33wMnABGBv4CbgXTP7lZnt\nkYUxiogAcMA+lQzfq4Jvnro7//eh7vkejohIRuzQOmNmdhBwNnAGEAPuAWYQ3DG7Cuju7odnfphJ\nx6KeMZES1BxzKqJa1FVEikuqnrF0G/i/SVCEHQw8TdDI/6i7tyQcsydQ5+45WdVfxZhIuNXV1TNl\n6nRWNsToVx1l0oRzqa2tyfOoRER2TiYa+C8DHgf2dvcT3P2hxEIsbgVw4S6Ms6CFfS5becWZFda8\nurp6Ro+7kfnNY6jfcAjzm8cwetyN1NXVZz07jO+n8sKRF+ZrK4W8VNItxoa5+1XuvqirA9x9s7v/\nPEPjEpESNmXqdCprxhOJVgEQiVZRWTOeKVOn53lkIiKZl+405Thgvbvf22H/aKCnu0/L0vhSjUnT\nlCIhdfIZE1nbu/ON9t5r7+Th39yQhxGJiOyaTExTTgCWJ9m/JP7ajgzmODN7w8zmm9nELo45zcz+\nZ2avmNnMHTm/iBS/XlXltMYat9nXGmukX3U0TyMSEcmedIuxvYC6JPvfjb+WFjMrA+4AjgU+BIw2\ns/06HLMvMBE4wt0PBL6d7vmzKexz2corzqww5rW1OZWDvkjd3FtojTWyZskcWmONbK6/nUkTzs1q\nNoTv/VReePLCfG2lkJdKusXYCuDAJPsPBlbtQN5hwFvuvtDdY8B9wEkdjjkPuNPd1wG4+8odOL+I\nFLn7n1nP2yv3YP/Dvk6N/ZoeG//A8IqZ3HvXpfo0pYiEUro9YzcCXwbOBP4e3/0J4G7gIXf/Xlph\nZl8CjnXlJ5SNAAAgAElEQVT3cfHtMcBh7j4+4ZiHgfnAkQTF4mR3/3OSc6lnTCRk2tqc7966gpcX\nbGbKN/tz+AFa2FVEwiFVz1i6a4JdAXwAeA5oju+LAo8Bk3ZkLEn2dayoyoF9gaMIpkD/ZmYfar9T\nJiLhVVZmTL14AP95rUmFmIiUjLSKMXffDJxsZgcCIwmKqhfc/dUdzFvMtj1mQ4GlSY6Z4+5tQL2Z\nvUlQCP6348nGjh1LTU0NANXV1YwcOZJRo0YBW+eCM7V96623ZvX8ygtPXmIfgvJ2fLs8YjSt+hez\nZ4fz+pSnvJ3d7pipvMLOa/++vr6e7XL3nH0BEWABMAyoAOYB+3c45ljgV/Hv+wELgd2TnMtzadas\nWcpTXsFlKU95yiudvDBfWynkxeuWpPVR2s+mNLMa4BSCO1sVHQq6b6Z1kuA8xwG3EfSDzXD3681s\nMjDX3R+PH3MzcBzQAlzr7g8kOY+nO3YRERGRfMrEsyk/AzwKvEGwJMVLwN4Ed7r+7e6fzdxw06Ni\nTKT4tbY5v35iLSeP6kXvnpF8D0dEJGsysejrFOB6d/8wsBn4CsEdsucIirTQS5wDVp7yCiWr2PPu\n/8t67nliHZfcvoKufrkq5utTnvKKNUt5uZVuMbYf0L4SfgvQ3d03Aj8ELsnGwEQk3N5cuJlfPNoA\nwNlfqMYs6S+MIiKhl+405XLgU+7+upm9Blzm7o+a2UHAP929Z7YHmmRMmqYUKVKbmto4//rlLF7R\nwimjenLRaX3yPSQRkazKxDpj/wY+BrwOPAncZGb7A1+KvyYikrY7H1zD4hUt7D04yriTd8/3cERE\n8irdacpLCJahALgS+CdwDsFjks7JwrgKTtjnspVXnFnFmNfW5vSqKqMyavzg7L5URFNPTxbb9SlP\neWHIUl5ubffOmJmVA0OAFwHcfT3w9SyPS0RCqqzMOP+U3Tn16N3o21ufoBQRSbdnrIlgcda67A8p\nPeoZExERkWKRiaUtXgVqMzckEREREYH0i7FJBE37x5lZfzOrSvzK5gALRdjnspVXnFnKU57ySicv\nzNdWCnmppFuMPQl8GHgCWA6s7/AlIpJUY1Mb37vtPV56qynfQxERKUjp9owdm+p1d/9zxkaUJvWM\niRSHG3+9iifnbGTfPaP8bOJAysq0uKuIlJ5dXmcsH8WWiBS/2S808uScjVREjUlj+6kQExFJIq1p\nSjP7YKqvbA+yEIR9Llt5xZlVyHnvrW7hlt+sAuCCU6qpGRTNal6mKE95hZoX5msrhbxU0l2B/1XA\ngfZfazvOD2qxIBHZwt25/u5VbNjkHHFgd75wVM6fmCYiUjTS7Rkb0WFXlKChfyLwfXd/LAtj296Y\n1DMmUsCef2UT0x9tYOr4AVT30u9rIlLaUvWMpVWMpTjx8QTF2FE7fZKdz1YxJlLg2tpcfWIiImRm\n0deuvAUcuovnKAphn8tWXnFmFXpeJgqxQr4+5SlPf7coLxPS6hlLsrCrAYOAq4EFmR6UiIiISKlI\nt2esjc5N+wDvAV9x979lemDbo2lKkcKycVMbPbrv6s12EZFw2uV1xoAT2LYYawPeB15z9+ZdHJ+I\nFLnlq1q44IblnPKpXpxx7G7qExMR2QFp/Rrr7k+6+58Tvp5293mlVIiFfS5becWZVQh5ra3Odb9a\nxdoNbcxf2IxluA7L9/UpT3mFkhfmayuFvFTSXfR1nJmNTrJ/tJmdl/lhiUix+O2f1/HK25vp2zvC\nhDF9sExXYyIiIZduz9h84Hx3n9Vh/1HANHfvuA5Z1qlnTCT//vfOZi6+5T3a2uDGb/XnI/t3z/eQ\nREQKUiaWttgLqEuy/934ayJSYtydO+5fQ1sbfPnoXirERER2UrrF2ArgwCT7DwZWZW44hSvsc9nK\nK86sfOaZGVef34+TjurJOV+oznperihPeYWaF+ZrK4W8VNItxu4DbjezT9hWRwG3Ar/bkUAzO87M\n3jCz+WY2McnrZ5nZCjN7If519o6cX0Ryp//u5Vx8eh8qouoTExHZWen2jFUSFGQnAe2foIwCjxGs\nM7Y5rTCzMmA+cDSwFJgLnO7ubyQccxZwqLuP38651DMmkkN1dfVMmTqdlQ0x+lVHmTThXGpra/I8\nKhGR4rDL64zFi62TzewAggeEG/CCu7+6g2M5DHjL3RfGB9Ze4L3R4Tj9mi1SQOrq6hk97kYqa8YT\n6V3F6uZGRo+7kXvvulQFmYjILkp3aYsyM4u4+6vu/mt3v8fdXzWzSPxuV7qGAIsSthfH93V0ipnN\nM7P7zWzoDpw/a8I+l6284szKVd6UqdODQixaxZolc4hEq6isGc+UqdOznh3G91N5yiv0LOXlVror\n8D8IzAFu6rD/28DHgC+leZ5kd7w6zjU+CvzW3WNmdj5wN8G0Zidjx46lpqYGgOrqakaOHMmoUaOA\nrW9yprbnzZuX0fMpL9x5Ydt+/c232djjJXYfcgQAa5bMAWBlz1hBjE/b2i6F7XbKK4689u/r6+vZ\nnnR7xt4HPu3ur3TYfwDwjLvvsd2TBMcfDlzl7sfFty8D3N1v6OL4MmC1u3f6qJZ6xkRy5wujv8/a\nnmcRiVZt2dcaa2R4xUym3XltHkcmIlIcMrHOWE+2Nu4nagF224GxzAX2NbNhZlYBnE5wJyxxsAMT\nNk8CXtuB84tIhv33jSZWRz9P3dxbaI01AkEhtrn+diZNODfPoxMRKX7pFmOvAqcl2X8aO1AsuXsr\ncBHwFPA/4D53f93MJpvZ5+KHjTezV83sxfixY9M9fzZ1vK2pPOUVQla28xYsauaHP3+fip5DOXfc\nhQyPzqR5/kSGV8zMWfN+mN5P5SmvWLKUl1vp9oxdCzxoZjXAs/F9RwNjgK/sSKC7PwmM6LDvyoTv\nJwGTduScIpIdA/uVM3yvCvpXR7jsrD0pKzuY2bNnb+mNEBGRXZdWzxiAmX0RuJxg1X2Al4D/5+4P\nZ2ls2xuPesZEcqA55pSVQXlEK86IiOysVD1jaRdjhUbFmIiIiBSLTDTwl7ywz2UrrzizlKc85ZVO\nXpivrRTyUkmrGDOzcjP7vpm9bGYNZtaY+JXtQYpI9rW0Ovc9vY5Yi+44i4jkUrrrjF1L8KnGm4Dr\ngauBWuAUgnXD7sjiGLsak6YpRTKkrc257u5VPDO3kU9/pIrLz+6X7yGJiIRKJqYpvwqc7+63Eawt\ndr+7jyMoyj6emWGKSD64Oz95cA3PzG2ke6Xx5aN75XtIIiIlJd1ibCDQvvr+BqB3/PvHgeMzPahC\nFPa5bOUVZ1Ym8n7753U8NHsD0XK4+vz+jBhWmdW8HaU85Skv91nKy610i7HFBAUZwDtsfVbkocDm\nTA9KRHLjry82MuPRtZjB98f249D9uuV7SCIiJSfdnrGbgQZ3v8bMRgP3AAsI+sZ+7O6XZHeYScek\nnjGRXdTU3MbV01dy+AHd+cJRmp4UEcmWjK8zZmafBI4E5rv7g7s4vp2iYkwkM9ranLIyLegqIpJN\nGV9nzN2fc/cp+SrE8iHsc9nKK86sTOTtaCFWbNenPOWFJS/M11YKealo0VcRERGRPNLjkERKxMqG\nFu55Yh3fPLWabhX6PUxEJJdSTVOW53owIpJ76xvbmHjH+9QtjRGJwMVf6ZPvIYmISJx+PU5T2Oey\nlVecWenkNTW3MeknK6hbGmPYwHLGntg75fG7mpdpylOe8nKfpbzcSvfZlE+YWae/wc2sl5k9kflh\niUgmtLQ6k6et5H/vNDNg9wg3XDSA3j0j+R6WiIgkSHedsVZgkLuv6LC/P7DU3aNZGl+qMalnTGQ7\nfvf0On7+cAO79Sjj9u/twV4Dc/6/qoiIsAs9Y2b2wfZvgeFmlvj04AhwHLA0I6MUkYw7eVQvFi6P\n8flP9FQhJiJSoLY3TfkqwTMpHXgu/n3710vANcB12RxgoQj7XLbyijNre3kVUePSr/Vl/5rUz5vM\nVF42KE95yst9lvJya3ufptyf4K7Ya8AngJUJrzUDy9y9KUtjExEREQm9dHvGKt29oB4Irp4xkc7c\nHTM92khEpNBk4nFIx5vZpxNOeKmZLTCzR+JN/CKSZ/PmN/H9O99n46a2fA9FRER2QLrF2LVABYCZ\nHUzQK3YP0Ae4OTtDKyxhn8tWXnFmtee9taiZy3/2Pv9+rYlH/7Yh63m5pDzlKS/3WcrLrXRX4K8B\n3oh/fwrwiLtfbWaPA1pnTCQP6urqmTJ1Oi+/uoCG2KP03edUjh81nNOO6ZXvoYmIyA5It2dsNfBx\nd3/NzP4O3OPud5lZDfCau1elHWh2HHArwV25Ge5+QxfHnQrcD3zE3V9I8rp6xqRk1dXVM3rcjVTW\njCcSraI11sjSeT/ij7+9jOEfqM338EREpINM9Iz9A7jBzC4BDmPr3bAPAEt2YCBlwB3AscCHgNFm\ntl+S43oC3wKeT/fcIqVkytTpWwoxgEi0isEjv8NNt87I88hERGRHpVuMfQvoBpwLXOzui+P7vwA8\nswN5hwFvuftCd48B9wEnJTnuGuAGoGA+wRn2uWzlFVfWyobYlkJszZI5QFCQrWyIZT07zH92ylNe\nIeeF+dpKIS+VtHrG3L0e+EyS/d/awbwhwKKE7cUEBdoWZjYSGOruT8TvxIlIB/2qo6xubtxSkAG0\nxhrpV61V9kVEik1aPWMAZhYlmF7cB/ilu68zsz2Bte6+Ls1znAp81t3HxbfHAB9194vj2wY8C5zl\n7u+a2Sxggrv/N8m51DMmJStZz9jm+tu5965Lqa2tyfPoRESko51+NmXCCWqAp4E9gCrgMWAd8D2g\nO3B+mmNZDOyVsD2UbZ9t2Yugl2x2vDAbCDxiZl9I1sQ/duxYampqAKiurmbkyJGMGjUK2Hr7Udva\nDuP2woX1XHz2UTz795msbIjRvHEp3zj7xC2FWL7Hp21ta1vbpb7d/n19fT3b5e7b/QIeAX4FRIH1\nwN7x/Z8EFqRzjvjxEWABMIxg3bJ5wP4pjp8FfLiL1zyXZs2apTzl5TVr+aqY//DnK3zNupac5HVF\necpTXn7ywnxtpZAXr1uS1jvprjN2JHCku8c6PGplITA4zXPg7q1mdhHwFFuXtnjdzCYDc9398Y4/\nQvBsTJGStqmpjR/89H3eWRKjqlsDE8/sm+8hiYhIhqS7ztgagmLsNTNbDxzs7u+Y2ceB37v7Htke\naJIxeTpjFyl2rW3OlXet5J8vb2LogHLuvHQgvarK8j0sERHZAZlYZ+xpguUt2rmZ9QCuBJ7cxfGJ\nSAozHmngny9voldVGVO+2V+FmIhIyKT7t/oE4Fgze5lgvbF7gHeAWmBilsZWUBIb8pSnvFxl/feN\nJu57ej2RMrjyvH4MHdB56Yowv5fKU57y8pOlvNxKd52xd83sIOBrwKEERdzvgLvdfX0WxydS0j48\nvJIzjt2NAX0iHDKiW76HIyIiWZCyZ8zMfkGw4n7BFVzqGRMREZFikapnbHvFWCswyN1XZGtwO0vF\nmIiIiBSLXWng17IScWGfy1ZecWYpT3nKK528MF9bKeSlkk4Dv24/ieTI759dx/sNLfkehoiI5ND2\npinbSKMYc/dIJgeVDk1TStg8/vcN3PLb1QzsG+FXPxxMRVQ3pkVEwmJXn005DmjI7JBEJNELbzZx\n232rATjzhN4qxERESkg605SPufvvU31lfZQFIOxz2crLX9ai92JMnraS1jY4/TO9OO6InlnN21XK\nU57y8pMX5msrhbxUtleMaR5QJIsa48+cXN/YxscO6s45J1Xne0giIpJj6fSMDdTSFiLZ4e789s/r\neO6FRm777h5076ZHHYmIhNFOrzNWyFSMSZg0x1x9YiIiIZaJB4WXvLDPZSsvv1m7UoiF+b1UnvKU\nl58s5eWWijERERGRPNI0pUgOvbs8Rnm5MbhfOqvKiIhIWGiaUqQArN3Qyvd/8j4X3rictxc353s4\nIiJSIFSMpSnsc9nKy25WrMW58q6VLFvZwoDdIwzun7k7Y2F+L5WnPOXlJ0t5uaViTCTL3J1b713N\nyws207d3hGsv6E/3Sv2vJyIiAfWMiWTZ/X9Zx88eaqAyatz63QGMGFaZ7yGJiEiOqWdMJI/KI0ZZ\nGUw8q68KMRER6UTFWJrCPpetvOxlnfKpXtxz1WBGHVKVk7xsU57ylJefvDBfWynkpaJiTCQHtJSF\niIh0RT1jIhlSV1fPlKnTWdkQo191lEkTzqW2tibPoxIRkUKgZ1OKZFldXT2jx91IZc14ItEqWmON\nbK6/nXvvulQFmYiIFFYDv5kdZ2ZvmNl8M5uY5PXzzexlM3vRzP5qZvvleozJhH0uW3m7ZsrU6VsK\nsTVL5hCJVlFZM54pU6dnNRfC914qT3nKy3+W8nIrp8WYmZUBdwDHAh8CRicptn7j7ge5+4eBm4Af\n5XKMIjtjZUOMSHTbBv1ItIqVDbE8jUhERIpFTqcpzexw4Ep3Pz6+fRng7n5DF8ePBsa4+4lJXtM0\npRSMo784kZb+X9+mIGuNNTK8YibT7rw2jyMTEZFCUEjTlEOARQnbi+P7tmFm3zSzBcD1wPgcjU1k\np8z801o29TqJurm30BprBNjSMzZpwrl5Hp2IiBS6XH/ePllF2On2lrv/BPiJmZ0OXAGMTXaysWPH\nUlNTA0B1dTUjR45k1KhRwNa54Ext33rrrVk9v/KKN2/PPaLENi7ia6d+jBXLZvL6m2/Tu2c53zj7\nxC3N+9m8vsS+h1y8n8pTnvLyk9cxU3mFndf+fX19Pdvl7jn7Ag4HnkzYvgyYmOJ4Axq6eM1zadas\nWcpTXpdWrInlLKsj5SlPeaWRF+ZrK4W8eN2StN7Jdc9YBHgTOBpYBvwbGO3uryccs6+7L4h//3ng\nCnc/LMm5PJdjFxEREdlZqXrGcjpN6e6tZnYR8BRBv9oMd3/dzCYDc939ceAiMzsGaAbWAGflcowi\nIiIiuVSW60B3f9LdR7j7B9z9+vi+K+OFGO7+bXc/wN0PcfejE++a5VPiHLDySjfv98+uY978ppxk\npUt5ylNeaeSF+dpKIS+VnBdjIsXqgWfWceeDDUz66fusXtea7+GIiEhI6HFIImn4/bNBIQbwvTP6\ncOKRPfM8IhERKSaFtM6YSNF5aNb6LYXYd7+qQkxERDJLxViawj6Xrbzklq9q4WcPrQHg26fvzuc+\nvv1CrFiuTXnKU15x5YX52kohL5VcL/oqUlQG9i3nyvP6sbKhlS8c1SvfwxERkRBSz5iIiIhIlqln\nTERERKRAqRhLU9jnspUXWL1215esKNRrU57ylFfceWG+tlLIS0XFmEjcn/65gTFXLmXua5vyPRQR\nESkh6hkTAf40ZwNTZ67GHS74UjVfPnq3fA9JRERCRD1jIin8+fmthdi4L6oQExGR3FIxlqawz2WX\nat5T/9rIjb8OCrFzT+rN6Z/d9UKsUK5NecpTXrjywnxtpZCXitYZk5JW3bOM8giceUJvvnps73wP\nR0RESpB6xqTkLV3ZwuB++r1ERESyJ1XPmIoxERERkSxTA38GhH0uW3nFmaU85SmvdPLCfG2lkJeK\nijEpGc+90MicV7SGmIiIFBZNU0qo1dXVM2XqdBYs2szC5a0M3u9UfnvjR9lrYDTfQxMRkRKSappS\nXcsSWnV19YwedyOVNeOJDK1izz0aWfnqrbQ0DgJq8z08ERERQNOUaQv7XHYY8yZfPy0oxKJVrFky\nh0i0in4HfJvrbp6R1dwwvpfKU57y8p8X5msrhbxUVIxJaK1Z10IkWrXNvki0ipUNsTyNSEREpDP1\njElonXfh5cxvHrNNQdYaa2R4xUym3XltHkcmIiKlRktbSGg1NrXx4LPr+MfLjZ1emzThXDbX305r\nLHitNdbI5vrbmTTh3FwPU0REpEsqxtIU9rnsYstbsbqFnz20hq9MWsJPHmzg7sfX0vFOaW1tDffe\ndSnDK2bSPH8iwytmcu9dl1JbW7NL2dtTbO+l8pSnvOLIC/O1lUJeKjn/NKWZHQfcSlAIznD3Gzq8\n/h3gXCAGvA+c7e6Lcj1OKUzrG9u47b7VzH6hkba2YN9B+1by5aN7JT2+traGaXdey+zZsxk1alSu\nhikiIpK2nPaMmVkZMB84GlgKzAVOd/c3Eo75JPAvd28ys28Ao9z99CTnUs9YCWptc868ahnvrW5h\n1CFVfPnoXowYVpnvYYmIiKRUSOuMHQa85e4LAczsPuAkYEsx5u7PJRz/PHBGTkcoBS1SZlx2Zh8G\n9Clnjz5aJk9ERIpfrnvGhgCJU46L4/u6cg7wp6yOKE1hn8supLyVDS3MeKSBx/62PunrB+7bbYcL\nMfV1KE95yiv2vDBfWynkpZLrWwvJbs8lnWs0szHAocAnszoiKRhvL27mgWfW8+x/NtLSCv2rI5zw\nsZ5EIknv6oqIiIRCrnvGDgeucvfj4tuXAZ6kif8Y4DbgKHdf1cW5/KyzzqKmpgaA6upqRo4cuaVJ\nu73i1Xbhbzc2tfH1CX9g/qIYuw85gjKDod1f4JMfruLrZ3w27+PTtra1rW1ta3tHt9u/r6+vB+Du\nu+/usmcs18VYBHiToIF/GfBvYLS7v55wzIeBB4Bj3f3tFOdSA38Ran9w98qGGP2qo0yacC41NcO4\n6Kb3qFsW44QjenDKp3djcD/1g4mISHgUzKKv7t4KXAQ8BfwPuM/dXzezyWb2ufhhNwI9gAfM7EUz\n+0Mux9iVxEpXeTunrq6e0efdyPzmMdRvOIT5zWMYPe5G6usXcunX+nL//xvCRaf1yUohlsv3M4x/\ndspTnvLynxfmayuFvFRyfvvB3Z8ERnTYd2XC95/J9Zgku1panedf2cR3LrmDqtrxWx5PFIlWUVkz\nnilTp+vxRCIiUrL0bErJmkXvxfjTPzfw539tZM26Nur+fQu1h32303G9197Jw7+5IckZREREwqGQ\n1hmTEtGwvpWvX7Nsyyr5wwaWU75XJZtjjZ0e3N2vOpqnUYqIiORfTnvGilnY57IznVfdK8JRI6s4\n/oge/HjCHvziikH8/OYLtjy4e82SOTl9cLf6OpSnPOUVe16Yr60U8lLRnTHZaRsa23hm7kZGDKtg\nv5rOjyS64py+mG29I1tbGzy4e8rU6by+8W2GV7zCpBw8uFtERKSQqWdMdoi78/Jbm3ninxt47sVN\nNMecYw6rYtLYfvkemoiISMFSz5hkxFuLmrlmxkoWr2jZsu+QEZV8/OCqFD8lIiIiqahnLE1hn8tO\nJ29Q33JWrGmlb+8IY47fjZlXD2bqxXtw1Id3vBgrxOsrxizlKU95pZMX5msrhbxUdGesxLWviP/6\nm2+z/wN/YdKEc+nWayj9d49Q3uGZkD2ryrhjwh7UDo7qeZEiIiIZop6xElZXV8/ocTdSWRMsxNoa\na2TpvB/Rf7+zuOF7I/nESE0/ioiIZELBPA5JCsuUqdO3FGIQrIg/eOR3eG/+gyxf1bKdnxYREZFM\nUDGWpjDOZa9siG0pxNYsmQMEBdmHaqN8+ejdspodxvczH1nKU57ySicvzNdWCnmpqGcspNydd5e3\n8PKCJl5ZsJnWNrjinG2Xn+hXHWV1c+cV8ffoqxXxRUREckU9YyGzvrGNm369ilfe3szaDW1b9kfL\n4bGb96QiunW6OlnP2Ob627lXC7GKiIhkVKqeMRVjRao55kTL2WaFe4C2NufkS5ewvrGNvr0jHLRv\nJQfuW8lB+1ZSMyhKWdm2x7d/mnJlQ4x+1VEmTThXhZiIiEiGqYE/A3I1t1xXV895F17Ox48ZzXkX\nXk5dXT0AGze18e//bWL6Iw1cfPN7fP57i1j6fucm+7Iy44pz+vLryYO4f8pgrjinH1/8ZC/2HlLR\nqRCD4BFF0+68lovPO55pd16bs0IszL0BYb425SlPefnLC/O1lUJeKuoZKyCJ04Ybe7zE/OaDGT3u\nRj7x2XN5sb4fbQk3As3g7SUxhgzo3N/1kf2753DUIiIisis0TVkANm1uY8GiZq6/7moWl53ZqaGe\nZb+gouYiRgyriE87duOAfSrpVaUbmyIiIsVAz6YsMEvejzH3tSbeXNjM/HebWbgsRpvDxkWb6bHv\ntgutRqJV9OhpPHDLULpVqPgSEREJG/3rnqadmVvu6s7di29u5vbfreHPz2+kbmkMM9h3zyjVvcqD\nO2FsXferNdbIwL7RrBdiYZ+rV1+H8pSnvGLPC/O1lUJeKkV9Z+y8Cy8vmE//tbY6774X442Fzcxf\n2Myb7zYzqF85V5zdr9OxB+xTybGH92DEsApG7FXBPkMrqIgadXUXbOkZA7YsNTHprktzfTkiIiKS\nI0XdM3bUua9nfV2sdJZ+WLComfE3v0dT87bv5YDdI9z3/4ZkPE9ERESKS2jXGfvUBQtpjTWy4rVp\nfPQz36Oi3Lj52wPo3TPS6fgf3786vjaXbfN12jG96F7ZeQpw7mubWLJkIZOvvY3dhl+cclHUTU1t\nfP57i9mjT4QRwyoZHr/j9YG9KujZXTPBIiIipS7U64xFolU0bW5l8YoW3lkaS7qWFsBT/9rIH/+x\nkT88t4EHnlnPb/+8jrv/uJaW1uTnvWbGSr4z6a4thdiaJXOIRKuorBnPlKnTtzm2e7cy/nDTUH5z\nzRB+eG4/Tv/Mbnx4RLddKsTCPnce5rwwX5vylKe8/OWF+dpKIS+Vou4Zg6Cv6siRPZjyw0HEWpyq\nbsmLsfGn9aGpuY1YCzS3OC0tTqzFqYwmP/7Q/btT/x+2WWYCgu2VDbFOx/fUMhMiIiKyE4p6mjLb\nPWPnXXg585vHdFr3a3jFTKbdeW3G80RERCScCmqa0syOM7M3zGy+mU1M8vonzOy/ZhYzs1NSnWt4\nxcysNu9PmnAum+tv37LcxJZPN044Nyt5IiIiUnpyWoyZWRlwB3As8CFgtJnt1+GwhcBZwG+2d75s\nP0uxtraGe++6lOEVM2mePzHrxV+isM+dhzkvzNemPOUpL395Yb62UshLJdc9Y4cBb7n7QgAzuw84\nCdCDkeIAAA8sSURBVHij/QB3fzf+WkHMn9bWBg/Snj17NqNGjcrzaERERCRsctozZmZfAo5193Hx\n7THAYe4+PsmxvwQec/eHujhXaJ5NKSIiIuFWSM+mTDaIna6oxo4dS01NDQDV1dWMHDlyy92r9tuP\n2ta2trWtbW1rW9u53m7/vr6+nu1y95x9AYcDTyZsXwZM7OLYXwKnpDiX59KsWbOUp7yCy1Ke8pRX\nOnlhvrZSyIvXLUlrmrLtl2sZNRfY18yGmVkFcDrwaIrjky8CJiIiIhISOV9nzMyOA24j+CTnDHe/\n3swmA3Pd/XEz+wjwMFANNAHL3f3AJOfxXI9dREREZGeE9tmUxTp2ERERKS0FtehrsUpsyFOe8gol\nS3nKU17p5IX52kohLxUVYyIiIiJ5pGlKERERkSzTNKWIiIhIgVIxlqawz2UrrzizlKc85ZVOXpiv\nrRTyUlExJiIiIpJH6hkTERERyTL1jImIiIgUKBVjaQr7XLbyijNLecpTXunkhfnaSiEvFRVjIiIi\nInmknjERERGRLFPPmIiIiEiBUjGWprDPZSuvOLOUpzzllU5emK+tFPJSUTEmIiIikkfqGRMRERHJ\nMvWMiYiIiBQoFWNpCvtctvKKM0t5ylNe6eSF+dpKIS8VFWMiIiIieaSeMREREZEsU8+YiIiISIFS\nMZamsM9lK684s5SnPOWVTl6Yr60U8lJRMSYiIiKSR+oZExEREcky9YyJiIiIFKicF2NmdpyZvWFm\n881sYpLXK8zsPjN7y8zmmNleuR5jMmGfy1ZecWYpT3nKK528MF9bKeSlktNizMzKgDuAY4EPAaPN\nbL8Oh50DrHb3DwC3AjfmcoxdmTdvnvKUV3BZylOe8konL8zXVgp5qeT6zthhwFvuvtDdY8B9wEkd\njjkJuDv+/YPA0TkcX5caGhqUp7yCy1Ke8pRXOnlhvrZSyEsl18XYEGBRwvbi+L6kx7h7K9BgZn1y\nMzwRERGR3Mp1MZbsUwQdPxLZ8RhLckzO1dfXK095BZelPOUpr3TywnxtpZCXSk6XtjCzw4Gr3P24\n+PZlgLv7DQnH/Cl+zL/MLAIsc/cBSc6V9wJNREREJF1dLW1RnuNxzAX2tf/f3rkHW1mVcfj54Tkq\noOA1yUjREq+Jt5AUxZIc1CIndQaxRO0yOZqkoyjijJes1FRwnPGPDLUwCsVLagpyUdMUFOUOKQYI\nSCDiDUYkhbc/1jrM52bfOOdbe58D7zPzzfkua63ft/ZZ693vXldpX+C/wADgnIIwTwCDgKnA2cDk\nYgmVypDjOI7jOE5boqbOmJltkHQJ8Ayhi3Skmc2XdAPwqpk9CYwERklaAKwmOGyO4ziO4zhbJW12\nBX7HcRzHcZytgTa3Ar+kWyXNlzRD0sOSOmWeDY2Lxc6XdEpOemdJmiNpg6SjMvcbJN0vaZakuXH8\nWxKt+OxwSS/F5zMlbZ9SLz7fR9IaSZe3VKucnqS+kqbFfL0q6dsp9eKz3MtKQfo94qLF0yW9IumY\nvDWKaP4yLqg8W9LNqfWi5hWSNqae8Vyu3uesU3ZR6py1ukqaLGle/J9dmlIvaraT9Lqkx2ug1VnS\nQ/H/NlfSsYn1Lov1fZakv+RhIwvSHylppaRZmXu7SnpG0huSxkvqnFgvWT0oppd5lns9L6WXyo6V\n+DxrbqdLYmZt6gD6Au3i+c3A7+L5IcB0QtdrN+AtYstfC/UOBA4gjF07KnP/HGB0PG8PLAL2SaS1\nHTATOCxe75oyb5nnY4ExwOU5/e9K5a8H0CWeHwosS6x3cIqyUqA9Hjglnp8KPJtn+kX0TiJ0/zfE\n6z1S6kWNrsC4WPZ3S6xVtN7nrNEuloV9gUZgBnBQwjx1AY6I5zsBb6TUizqXAQ8Aj9egfNwPXBDP\nG4BOCbX2BhYC28frMcB5OWv0Bo4AZmXu3QIMiedXATcn1ktWD4rpxftJ6nmJ/CWzYyX0amqnyx1t\nrmXMzCaa2cZ4OYVQUAD6A38zs8/NbDGwgLDIbEv13jCzBWy+5IYBHRVmfHYA1gMfJ9I6BZhpZnNi\nuA8slp5Eekj6AfAfYG5LdSrpmdlMM1sRz+cCO0hqTKVHWFg497JSwEag6VfyLsA7OadfyEWEL4LP\nAczsvcR6AMOBK2ugU67e50k1i1LnhpmtMLMZ8XwtMJ/N113MDUldgdOAP6bSyGjtDJxgZvcBxLrW\nIvtYBdsRbHIDwSYvzzNxM3sR+KDgdnaR8j8BZ6TUS1kPSuQPEtXzEnrJ7FgJvVrb6ZK0OWesgAuB\np+J54YKy75DQsBFajT4hzApdDNxmZqmW8+0OIGlc7M5L+gUoqQMwBLiB4mvDpdQ+C5gevwxTUYuy\nchlwm6QlhC29huacfiHdgRMlTZH0bOrmdknfB5aa2eyUOiW4EHg6QbrVLEqdBEndCL/apyaUafpS\nrcVA4f2B9yTdF7tF/yCpfSoxM1sO3A4sIdTnD81sYiq9DF8ys5XxHVYAe9ZAs4lU9WATdajnNbVj\n1N5Ol6TWS1tUhaQJwF7ZWwQDMszMnohhhgGfmdlfM2EKqcroVKNXhJ7A54Suht2BFyRNjC0teWs1\nAMcDxwCfApMkTTOzZ8tmrPl6NwDDzewTSU1xqqKZek1xDwV+B3w3sV6zy0q12oTuhMFm9lh0MO9l\nC/K1hXrXEsrILmbWS9I3gQcJX4ip9K7hi/lpsdO+hfV+dEv1ir1CkXvJHRdJOxF+3A2OLWQpNE4H\nVprZDEknkf5HVgNwFHCxmU2TNAK4GrguhZikXQitVPsCHwFjJQ1MVE7qTuJ60KTRnmDLcq3nFcjd\njlXgInK2082lVTpjZlb2w5A0iNDc/p3M7WXAVzPXXamymbqSXgkGAuNik/EqSf8iOEuLE2gtA543\nsw8AJD1FMHQVnbFm6h0LnCnpVsL4tA2S1pnZ3Yn0mrpQHgF+XMmhzUGv2WWlWm1Jo8xscAw3VtLI\nLX7LLdP7BeHzw8xejYNtdzez1XnrSTqMMNZupoK33hV4TVJPM3s3b72MbrF6nyfLgH0y180qF1tC\n7FIbC4wys78nlDoe6C/pNMIY150l/dnMzkukt4zQojItXo8ljKlKRV9goZm9DyDpEeA4ILUztlLS\nXma2UlIXoNnlv1pqUA+a+BoJ6nkFlpKzHavAoLztdHNpc92UkvoRutD6m9n6zKPHgQGStpe0H/B1\n4JW85TPnS4iVQVJHoBfw70Ra44HDJe0YjXcfYF6OWl/QM7MTzWx/M9sfGAH8thpHrLl6cQbSk8DV\nZjYlZ53N9KhNWXlHUh8ASScDb+acfiGPASdHve5AYyoDZmZzzKxLLCP7Eb54j0xooMvV+zzZtCi1\nwky8AYSykpJ7gXlmdmdKETO7xsz2iXV6ADA5oSNG7LpbGssihLKZt83KsgToFW2kot78BDpic1ty\nfjwfBOTtUH9Brwb1YJNejep54eeZ2o4V6tXaTpfG6jRzoLkHYbD128Dr8bg782woYTbUfOIMiRz0\nziB46+sI48Oejvc7EppQ58SjxTMOS2nFZwOjzixymkFTTi8T5ro88lbhsxwGrIn/z+nxb4tn0VT4\nPHMvKwXaxwHTYn5eJhixlPWiERgFzI66fVLqFWgvJP1sypL1PmedfoRZjQsIPw5S5ul4YANh1mZT\nue9Xg/9XH2ozm7IHwcGdQWjt6JxY77pYn2cRBtM35pz+aEJL6XqC83cBoedgYiwzEwhdbCn1ktWD\nYnoFz3Ot5yXy15DKjpXQq6mdLnf4oq+O4ziO4zh1pM11UzqO4ziO42xNuDPmOI7jOI5TR9wZcxzH\ncRzHqSPujDmO4ziO49QRd8Ycx3Ecx3HqiDtjjuM4juM4dcSdMcdxnApIOl9S2b0OJd0lqeKuGAVx\n9pT0rqS9W/aGjuO0ZdwZcxynVSJpD0l3S1ok6VNJKyRNiCtlN4V5Lm6ZMrAg7iBJazLXfWK4puM9\nSZMkHVfFezQCvwaur+K1Ny3cGDfJzmqukvSEpAM3BTZbRVig9MYq0nYcZyvFnTHHcVorjxD2e70A\nOAA4HXga2D0Txgg7LNwUnSYKnhVeHwx0IaxCvwr4h6Q9KrzH2cA6M3uxGXlo2vy8C2ED4vbEvfcy\n3A+cGze7dhxnG8SdMcdxWh1xv9LehC2JnjOzpWb2mpndYWYPFgQfA+wIXFxF0qvM7F0zmwvcBHQG\njq0Q5xwK9qiU1E7SbZLel7Ra0nBguyJx15tZk+YMYDhwkKQdmgLEd1kO/LCK93ccZyvEnTHHcVoj\na+PRP+u4lAl7I3CtpE4VwgpAUgfgQkJr2WcV4vQm7F+X5QrgJ8DPgG8RHLFzywpLOxM26Z5lm2/y\n/Aqhtc5xnG0Qd8Ycx2l1mNkGYBDwI+BDSS9J+r2kniWi3AOsBq4uk6yARXEs2RrgV4SNrCeVjBBa\n6DoTNprPMhi4xcweNrM34/WKIkmcKmlN1PwIOIHiTttyoFuZd3ccZyvGnTHHcVolZvYosDfwPeAp\nQgvUFEmbOVzReRsGXFpmZqIBJwFHElqoFgLnx7ilaB//ftp0I7a+fRmYktE3YGqR+M8DhwM9gJ7A\nZGCCpK8UhFuX0XIcZxvDnTHHcVotZvY/M5tkZjeZWW9gJHC9pIYiYccCsyk/M3Gxmb1lZg/FcI8W\nGfifZTXBidu1mVn4xMwWmdlCM5sG/BToBPy8INxuhAkFjuNsg7gz5jhOW2I+0EAYsF+Mqwjdm4dW\nkdYooJEyA//N7DNgHnBI5t7HhG7LXgXBS3WhFrIR6FBw7zDg9SrjO46zleHOmOM4rQ5Ju8V1wM6V\n9A1J3SSdDVwJTDSztcXimdk/gXHAJcWSLQhrwAhgqKRyXYTjCYP4s9wJDJF0pqTukkYQui4L2UHS\nXvE4CLgL6EhmdmbUPpqwbIfjONsg7ow5jtMaWQu8DFwKPAfMISxF8QBhvFcThWuJQRjE31jkWbGw\n9xJmQg4u8y73AP0K1gG7HbgvPptCcPQeKBK3L2Fw/vIY7mjgLDN7IRPmDOBtM3upzDs4jrMVo/Dj\n0HEcxymFpNHAXDP7TYK0pwJ3mNmYvNN2HKdt4C1jjuM4lRkCfJx3opL2BB5yR8xxtm28ZcxxHMdx\nHKeOeMuY4ziO4zhOHXFnzHEcx3Ecp464M+Y4juM4jlNH3BlzHMdxHMepI+6MOY7jOI7j1BF3xhzH\ncRzHceqIO2OO4ziO4zh15P8jtrrbfF9JwAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f2b454a8780>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech1\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.75  0.00   0.02  0.00  0.00   0.02   0.01  0.20\n",
      "BPSK   0.00  0.96   0.00  0.00  0.01   0.00   0.00  0.02\n",
      "CPFSK  0.00  0.00   0.99  0.00  0.00   0.00   0.00  0.00\n",
      "GFSK   0.00  0.00   0.01  0.99  0.00   0.00   0.00  0.00\n",
      "PAM4   0.00  0.04   0.00  0.00  0.95   0.00   0.00  0.00\n",
      "QAM16  0.16  0.00   0.00  0.00  0.00   0.44   0.35  0.04\n",
      "QAM64  0.00  0.00   0.00  0.00  0.00   0.45   0.54  0.00\n",
      "QPSK   0.05  0.00   0.00  0.00  0.00   0.01   0.00  0.95\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f2b4c034cc0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
